package com.yunao.commons.serachcore.core.query;


import com.yunao.commons.serachcore.core.help.*;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;

class QueryBuilderImpl implements QueryBuilder {

	QueryImpl query;

	public QueryBuilderImpl() {
		this.query = new QueryImpl();
	}

	@Override
	public QueryBuilder mode(Mode mode) {
		query.setMode(mode);
		return this;
	}

	@Override
	public QueryBuilder keywords(String keywords) {
		query.setKeywords(keywords);
		return this;
	}

	@Override
	public QueryBuilder title(String title) {
		query.setTitle(title);
		return this;
	}

	@Override
	public QueryBuilder timeGreaterThanOrEqualTo30Days() {
		long time = getDateTime(30);
		return timeGreaterThanOrEqualTo(time);
	}

	private long getDateTime(int days) {
		long time = LocalDate.now().minusDays(days).atStartOfDay(ZoneId.systemDefault()).toEpochSecond();
		return time * 1000l;
	}

	@Override
	public QueryBuilder timeGreaterThanOrEqualTo7Days() {
		long time = getDateTime(7);
		return timeGreaterThanOrEqualTo(time);
	}

	@Override
	public QueryBuilder timeGreaterThanOrEqualTo3Days() {
		long time = getDateTime(3);
		return timeGreaterThanOrEqualTo(time);
	}

	@Override
	public QueryBuilder timeGreaterThanOrEqualTo1Days() {
		long time = getDateTime(1);
		return timeGreaterThanOrEqualTo(time);
	}

	@Override
	public QueryBuilder timeGreaterThanOrEqualTo(long time) {
		query.setGreaterEqual(time);
		return this;
	}

	@Override
	public QueryBuilder timeGreaterThanOrEqualTo(int days) {
		long time = getDateTime(days);
		return timeGreaterThanOrEqualTo(time);
	}

	@Override
	public QueryBuilder timeGreaterThanOrEqualTo(String date) {
		long time = datestrToDateTime(date);
		return timeGreaterThanOrEqualTo(time);
	}

	private long datestrToDateTime(String date) {
		try {
			String pattern = date.length() == 10 ? "yyyy-MM-dd" : "yyyy-MM-dd HH:mm:ss";
			SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
			return dateFormat.parse(pattern).getTime();
		} catch (ParseException e) {
			throw new IllegalArgumentException("Parameters date error: " + date);
		}
	}

	@Override
	public QueryBuilder timeGreaterThan(long time) {
		query.setGreaterThan(time);
		return this;
	}

	@Override
	public QueryBuilder timeGreaterThan(int days) {
		long time = getDateTime(days);
		return timeGreaterThan(time);
	}

	@Override
	public QueryBuilder timeGreaterThan(String date) {
		long time = datestrToDateTime(date);
		return timeGreaterThan(time);
	}

	@Override
	public QueryBuilder timeBetween(String beginDate, String endDate) {
		long beginTime = datestrToDateTime(beginDate), endTime = datestrToDateTime(endDate);
		return timeBetween(beginTime, endTime);
	}

	@Override
	public QueryBuilder timeBetween(long beginTime, long endTime) {
		query.setBetween(new long[] { beginTime, endTime });
		return this;
	}

	@Override
	public QueryBuilder offset(int offset) {
		query.setOffset(offset);
		return this;
	}

	@Override
	public QueryBuilder limit(int limit) {
		query.setLimit(limit);
		return this;
	}

	@Override
	public QueryBuilder group(GroupField group) {
		query.setGroup(group);
		return this;
	}

	@Override
	public QueryBuilder cube(GroupField group, GroupField group2) {
		query.setGroup(group);
		query.setGroup2(group2);
		return this;
	}

	@Override
	public QueryBuilder miningField(String field) {
		query.setMiningField(field);
		return this;
	}

	@Override
	public QueryBuilder wordcloud(int maxWord) {
		query.setMaxWord(maxWord);
		return this;
	}

	@Override
	public QueryBuilder wordrelation(String... stopWords) {
		query.setStopWords(stopWords);
		return this;
	}

	@Override
	public QueryBuilder wordrelation(int maxWord, String... stopWords) {
		query.setMaxWord(maxWord);
		query.setStopWords(stopWords);
		return this;
	}

	@Override
	public QueryBuilder cluster(double distance, int maxGroup) {
		query.setDistance(distance);
		query.setMaxGroup(maxGroup);
		return this;
	}

	@Override
	public QueryBuilder id(long... ids) {
		query.setIds(ids);
		return this;
	}

	@Override
	public QueryBuilder trimArticle() {
		query.setTrimArticle(true);
		return this;
	}

	@Override
	public QueryBuilder nonTrimArticle() {
		query.setTrimArticle(false);
		return this;
	}

	@Override
	public QueryBuilder sort(Sort sort) {
		query.setSort(sort);
		return this;
	}

	@Override
	public QueryBuilder author(String... authors) {
		query.setAuthor(authors);
		return this;
	}

	@Override
	public QueryBuilder domain(String... domains) {
		query.setDomain(domains);
		return this;
	}

	@Override
	public QueryBuilder host(String... hosts) {
		query.setHost(hosts);
		return this;
	}

	@Override
	public QueryBuilder source(String... sources) {
		query.setSource(sources);
		return this;
	}

	@Override
	public QueryBuilder mediaType(MediaType... mediaTypes) {
		query.setMediaType(mediaTypes);
		return this;
	}

	@Override
	public QueryBuilder mediaType(String... mediaTypes) {
		query.setMediaType(mediaTypes);
		return this;
	}

	@Override
	public QueryBuilder channel(Channel... channels) {
		query.setChannel(channels);
		return this;
	}

	@Override
	public QueryBuilder channel(String... channels) {
		query.setChannel(channels);
		return this;
	}

	@Override
	public QueryBuilder emotion(Emotion... emotions) {
		query.setEmotion(emotions);
		return this;
	}

	@Override
	public QueryBuilder emotion(String... emotions) {
		query.setEmotion(emotions);
		return this;
	}

	@Override
	public QueryBuilder domainLevel(DomainLevel... domainLevels) {
		query.setDomainLevel(domainLevels);
		return this;
	}

	@Override
	public QueryBuilder domainLevel(String... domainLevels) {
		query.setDomainLevel(domainLevels);
		return this;
	}

	@Override
	public QueryBuilder messageType(MessageType... messageTypes) {
		query.setMessageType(messageTypes);
		return this;
	}

	@Override
	public QueryBuilder messageType(String... messageTypes) {
		query.setMessageType(messageTypes);
		return this;
	}

	@Override
	public QueryBuilder location(String... locations) {
		query.setLocation(locations);
		return this;
	}

	@Override
	public QueryBuilder isDomestic() {
		query.setDomestic(1);
		return this;
	}

	@Override
	public QueryBuilder isOverseas() {
		query.setDomestic(2);
		return this;
	}

	@Override
	public QueryBuilder nr(String... nr) {
		query.setNr(nr);
		return this;
	}

	@Override
	public QueryBuilder ns(String... ns) {
		query.setNs(ns);
		return this;
	}

	@Override
	public QueryBuilder nt(String... nt) {
		query.setNt(nt);
		return this;
	}

	@Override
	public Query build() {
		return query;
	}

}
